﻿using adb;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using System.Linq;
using Z.EntityFramework.Plus;
using Masuit.Tools.Security;
using System.Collections.Generic;
using PowerStation.RequestModel;
using Microsoft.EntityFrameworkCore;
using adb.excel;
using System.IO;
using Masuit.Tools;
using Microsoft.Net.Http.Headers;
using System;

namespace PowerStation.Controllers
{
    /// <summary>
    /// 计划发电管理
    /// </summary>
    public class PlanController : BaseApi<PlanController>
    {
        /// <summary>
        /// 计划发电管理
        /// </summary>
        /// <param name="content"></param>
        public PlanController(IHttpContextAccessor content) : base(content)
        {
        }



        /// <summary>
        /// 列表
        /// </summary>
        /// <param name="powerStationId">电站ID</param>
        /// <param name="searchTime">搜索月份</param>
        /// <param name="model">分页</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultApi<List<vPlan>>> List(decimal powerStationId,DateTime? searchTime,[FromQuery]PageModel model)
        {
            await this.IsCheckPowerStation(powerStationId);
            IQueryable<vPlan> q = this._db.vPlan.Where(x=>x.planPowerStation_powerStationId_fk == powerStationId);
            if (searchTime.HasValue) {
                q = q.Where(x => EF.Functions.DateDiffMonth(x.planMonth, DateTime.Now) == 0);
            }
            var result = await model.setPageAsync(q);
            return ResultApi.ok<List<vPlan>>(await result.Item2.ToListAsync(),result.Item1) ;
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="planId">计划ID</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ResultApi<bool>> Delete(decimal planId)
        {

            using (var tran = await this._db.Database.BeginTransactionAsync())
            {


                using (var deviceTran = await this._deviceDB.Database.BeginTransactionAsync())
                {
                    try
                    {
                        var m = await this._db.tPlan.FirstOrDefaultAsync(x => x.planId == planId);
                        await this.IsCheckPowerStation(m.planPowerStation_powerStationId_fk);
                        await this._db.tPlan.Where(x => x.planId == planId).DeleteAsync();
                        await this._db.SaveChangesAsync();
                        if (await UpdateData(m))
                        {
                            await deviceTran.CommitAsync();
                            await tran.CommitAsync();
                        }
                        return ResultApi.okOrError<bool>(true, true);
                    }
                    catch (Exception ex)
                    {
                        return ResultApi.error(false, ex.Message);
                    }
                    
                }

            }
        }
        /// <summary>
        /// 更新统计数据
        /// </summary>
        /// <param name="m">计划数据</param>
        /// <returns></returns>
        private async Task<bool> UpdateData(tPlan m) {
            try
            {
                
                    if (m.planType == 1)
                    {
                        var oldData = await this._deviceDB.tStatisticsData.FirstOrDefaultAsync(x => x.statisticsDataDate == m.planMonth && x.statisticsStation_powerStationId_fk == m.planPowerStation_powerStationId_fk && x.deviceGroup == "1#");
                        if (oldData != null)
                        {
                            oldData.planPowerOfYear = await this._db.tPlan.Where(x => EF.Functions.DateDiffYear(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planElectricQuantity) * 10000;
                            oldData.planInstallOfYear = await this._db.tPlan.Where(x => EF.Functions.DateDiffYear(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planInstalledValue);
                    }
                        else
                        {
                            await this._deviceDB.AddAsync(new tStatisticsData
                            {
                                statisticsDataDate = m.planMonth,
                                statisticsStation_powerStationId_fk = m.planPowerStation_powerStationId_fk.ConvertTo<long>(),
                                deviceGroup = "1#",
                                planPowerOfYear = await this._db.tPlan.Where(x => EF.Functions.DateDiffYear(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planElectricQuantity) * 10000,
                                planInstallOfYear = await this._db.tPlan.Where(x => EF.Functions.DateDiffYear(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planInstalledValue)
                            });
                        }
                    }
                    else
                    {
                        var oldData = await this._deviceDB.tStatisticsData.FirstOrDefaultAsync(x => x.statisticsDataDate == m.planMonth && x.deviceGroup == "1#");
                        if (oldData != null)
                        {
                            oldData.planPowerOfMonth = await this._db.tPlan.Where(x => EF.Functions.DateDiffMonth(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planElectricQuantity) * 10000;
                            oldData.planInstallOfMonth = await this._db.tPlan.Where(x => EF.Functions.DateDiffMonth(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planInstalledValue);
                        }
                        else
                        {
                            await this._deviceDB.AddAsync(new tStatisticsData
                            {
                                statisticsDataDate = m.planMonth,
                                deviceGroup = "1#",
                                statisticsStation_powerStationId_fk = m.planPowerStation_powerStationId_fk.ConvertTo<long>(),
                                planPowerOfMonth = await this._db.tPlan.Where(x => EF.Functions.DateDiffMonth(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planElectricQuantity) * 10000,
                                planInstallOfMonth = await this._db.tPlan.Where(x => EF.Functions.DateDiffMonth(x.planMonth, m.planMonth) == 0 && x.planType == m.planType && x.planPowerStation_powerStationId_fk == m.planPowerStation_powerStationId_fk).SumAsync(x => x.planInstalledValue),
                            });
                        }
                    }
                    await this._deviceDB.SaveChangesAsync();
                    return true;
                
            }
            catch (Exception ex) {
                Console.WriteLine($"更新统计数据出错:{ex.Message}");
                return false;

            }
        }

        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="planId">计划ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultApi<vPlan>> Detial(decimal planId)
        {
            var m = await this._db.vPlan.FirstOrDefaultAsync(x => x.planId == planId);
            if (m == null) return ResultApi.error<vPlan>(null, "数据丢失");
            await this.IsCheckPowerStation(m.planPowerStation_powerStationId_fk);
            return ResultApi.ok<vPlan>(m) ;
        }



        /// <summary>
        /// 新增
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultApi<decimal>> Create(tPlan model)
        {

            using (var tran = await this._db.Database.BeginTransactionAsync())
            {

                using (var deviceTran = await this._deviceDB.Database.BeginTransactionAsync())
                {
                
                    try {
                        model.planId = 0;
                        model.planUser_userId_fk = this.userId;
                        if (model.planType == 1)
                        {
                            model.planMonth = new DateTime(model.planMonth.Year, 1, 1);
                        }
                        else {
                            model.planMonth = new DateTime(model.planMonth.Year, model.planMonth.Month, 1);
                        }
                        await this.IsCheckPowerStation(model.planPowerStation_powerStationId_fk);
                        await this._db.tPlan.AddAsync(model);
                        await this._db.SaveChangesAsync();
                        if (await UpdateData(model))
                        {
                            await deviceTran.CommitAsync();
                            await tran.CommitAsync();
                        
                        }
                        return ResultApi.okOrError<decimal>(model.planId > 0, model.planId);

                    } catch (Exception ex) {
                        Console.WriteLine($"创建计划发电出错:{ex.Message}");
                        return ResultApi.error<decimal>(0,ex.Message);
                    }
                }

            }

        }


        /// <summary>
        /// 修改
        /// </summary>
        [HttpPut]
        public async Task<ResultApi<bool>> Modify(tPlan model)
        {

            using (var tran = await this._db.Database.BeginTransactionAsync())
            {

                using (var deviceDb = await this._deviceDB.Database.BeginTransactionAsync())
                {
                    
                
                    try {
                        if (model.planType == 1)
                        {
                            model.planMonth = new DateTime(model.planMonth.Year, 1, 1);
                        }
                        else
                        {
                            model.planMonth = new DateTime(model.planMonth.Year, model.planMonth.Month, 1);
                        }
                        await this.IsCheckPowerStation(model.planPowerStation_powerStationId_fk);
                        var oldModel = await this._db.tPlan.FirstOrDefaultAsync(x => x.planId == model.planId);
                        if (oldModel == null) return ResultApi.error<bool>(false,"数据掉丢,修改失败,请刷新再操作");
                        await this._db.tPlan.Where(x => x.planId == model.planId).UpdateAsync(x => new tPlan
                        {
                            planElectricQuantity = model.planElectricQuantity,
                            planInstalledValue = model.planInstalledValue,
                            planMonth = model.planMonth,
                            planUser_userId_fk = model.planUser_userId_fk
                        });
                        await this._db.SaveChangesAsync();
                        bool ok = await UpdateData(model);
                        if (model.planMonth != oldModel.planMonth) {
                            ok = ok && await UpdateData(oldModel);
                        }
                        if (ok)
                        {
                            await deviceDb.CommitAsync();
                            await tran.CommitAsync();
                        }

                        return ResultApi.okOrError<bool>(true, true);

                    } catch (Exception ex) {
                        Console.WriteLine($"修改计划数据出错:"+ex.Message);
                        return ResultApi.error<bool>(false,ex.Message); 
                    }
                }
            }

        }


        /// <summary>
        /// 导出数据
        /// </summary>
        /// <param name="powerStationId">电站ID</param>
        /// <param name="searchTime">搜索月份</param>
        /// <param name="model">分页</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<FileStreamResult> Download(decimal powerStationId, DateTime? searchTime, [FromQuery] PageModel model)
        {
            await this.IsCheckPowerStation(powerStationId);
            var m = await this.List(powerStationId,searchTime,model);
            var titles = await this._db.tExcelTitle.Where(x=>x.excelType == 9).ToListAsync();
            if (titles.Count == 0) return new FileStreamResult(new MemoryStream(), new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            Task<Stream> task = Task.Run(() =>
            {
                return ExcelExport.export<vPlan>(m.data, titles);
            });
            task.Start();
            return new FileStreamResult(await task, new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        }


    }
}
